{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8oCs7zcAvs5p"
      },
      "source": [
        "# colab版MMD自動トレースv2へようこそ！(実行編)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9GsUrjROxoDK"
      },
      "source": [
        "# 始めに\n",
        "\n",
        "このツールの稼働状況やメンテナンス情報はTwitter（[@miu200521358](https://twitter.com/miu200521358)）にて行っています。\n",
        "\n",
        "エラーになる、起動しない、などの場合、まずは現在の配布状況をご確認ください。\n",
        "\n",
        "リプやDM等でのお問い合わせも受け付けています。\n",
        "\n",
        "また、v2では会員登録後にダウンロードできる学習データが必要なため、会員登録をお願いしています。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oe_4TOdDx37F"
      },
      "source": [
        "# 目次\n",
        "\n",
        "このノートブックでは、MMD自動トレースの準備と実行を行います。\n",
        "\n",
        "ノートブックの使い方にはクセがあるので、「[準備編](https://colab.research.google.com/github/miu200521358/motion_trace_colab/blob/master/AutoTraceIntroduction.ipynb)」で使い方に慣れてください。\n",
        "\n",
        "画面左上の「＝」（実際は三本線）をクリックして下さい。目次が開きます。（既に開いている場合は次へ進んでください）\n",
        "\n",
        "![目次](https://drive.google.com/uc?export=view&id=1HGk4sJmcPtMbMwcJOvE3aU1GjvKinwA_)\n",
        "\n",
        "Googleドライブの直下に`autotrace`フォルダを作成してください。\n",
        "\n",
        "（準備編で既に作られている場合は再作成不要です）\n",
        "\n",
        "ノートブックを上から順に確認し、以下手順をひとつずつ実行してください。\n",
        "\n",
        "実行が必要なセルには番号を振ってあります。①から順番に実行してください。\n",
        "\n",
        "\n",
        "- **「①　データDL」**\n",
        "  - GoogleドライブおよびGoogleSDK（ツール）と連携します\n",
        "  - 連携のやり方は、導入編をご確認ください\n",
        "  - 人物推定に必要な学習データを事前にダウンロードしておきます。\n",
        "- **「②　環境設定」**\n",
        "  - ランタイムがGPUに変更できたことを確認します\n",
        "    - 変更のやり方は、導入編をご確認ください\n",
        "  - Tensorflowのバージョンを1.xに変更します\n",
        "  - 効果音を[効果音ラボ](https://soundeffect-lab.info/)様よりダウンロードします\n",
        "   - 準備や実際のトレース処理等、長い処理時に鳴らします\n",
        "   - 不要の場合は、ブラウザの音量をミュートにしてください\n",
        "- **「③　準備」**\n",
        "    - MMD自動トレースに必要なコードをcolab上に構築します。\n",
        "    - 大体15分くらいかかります。\n",
        "- **「④　データ配置」**\n",
        "    - MMD自動トレースに必要な学習データ等を配置します。\n",
        "- **「⑤　動画配置」**\n",
        "    - MMD自動トレースの対象となる映像データを配置します。\n",
        "- **「⑥　MMD自動トレース実行」**\n",
        "    - MMD自動トレースを実行します。\n",
        "\n",
        "---\n",
        "\n",
        "※作業中に下記のような警告が出ることがありますが、そのまま進めていただいて問題ありません\n",
        "\n",
        "　（GPUを使うのは主に人物推定とか姿勢推定などの一部分ですので、その他のセルを作業中に出る可能性があります。）\n",
        "\n",
        "![警告](https://drive.google.com/uc?export=view&id=1mRW32urnPQ4LS4xrLEoPdp_XCqlq1HUF)\n",
        "\n",
        "---\n",
        "\n",
        "※下記のようなエラーが出た場合、環境が既に破棄されています。\n",
        "\n",
        "目次からセル①に戻って、すべて実行し直してください。\n",
        "\n",
        "![Googleドライブ連携](https://drive.google.com/uc?export=view&id=1Tsjzs2QAECPMfUTaTh7PYX2cMEypEIF2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yYif75w8vuDT"
      },
      "source": [
        "# MMD自動トレース実行"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0zesaONCvUaQ"
      },
      "source": [
        "## 事前準備"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Stvjb4Icsq-A"
      },
      "source": [
        "人物推定に必要なデータを2件、それぞれのサイトに会員登録して、ダウンロードしてください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Q7_RGODpJYhK"
      },
      "source": [
        "1. [ExPoseプロジェクトページ](https://expose.is.tue.mpg.de) にアクセスしてください。\n",
        "\n",
        "2. 「SignIn」ボタンをクリックしてください。\n",
        "\n",
        "![SignIn](https://drive.google.com/uc?export=view&id=1__io7EjqFQnhq08Zi_YfxKUeSottZWJl)\n",
        "\n",
        "3. 「Register」ボタンをクリックしてください。\n",
        "\n",
        "![SignIn](https://drive.google.com/uc?export=view&id=1B8mJPJuTdHANo0UJ71Gue6CmznSDCdbw)\n",
        "\n",
        "4. 「メールアドレス」「パスワード」を入力して、スイッチをすべてONにして、「Register」ボタンをクリックしてください。\n",
        "\n",
        "![SignIn](https://drive.google.com/uc?export=view&id=1R2jCZHKJu71hXLW2KHhSLswDjwJEWEiZ)\n",
        "\n",
        "5. 届いたメールのリンクをクリックしてください。\n",
        "\n",
        "6. 登録した「メールアドレス」「パスワード」を入力して、「LogIn」ボタンをクリックしてください。\n",
        "\n",
        "![SignIn](https://drive.google.com/uc?export=view&id=1loay_bPetEBQfaOQIpS_JCLhZrFHolyF)\n",
        "\n",
        "7. 「Download」ボタンをクリックしてください。\n",
        "\n",
        "![SignIn](https://drive.google.com/uc?export=view&id=1GFhczKTl5Mc6E6PSRXT0hznCVfo-FWDr)\n",
        "\n",
        "8. 画面中程の「ExPose Model」ボタンをクリックしてください。\n",
        "\n",
        "![SignIn](https://drive.google.com/uc?export=view&id=1FjaHb9yGr52nI27xBLHAQBBz4gOEnR6x)\n",
        "\n",
        "9. ダウンロードしたzipファイル（expose_data.zip）を、`autotrace` フォルダに置いてください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Zf_DKKFJjK2R"
      },
      "source": [
        "1. [SMPL-Xプロジェクトページ](https://smpl-x.is.tue.mpg.de) にアクセスしてください。\n",
        "\n",
        "2. Exposeと同様に会員登録をしてください。\n",
        "\n",
        "3. 画面上部の「download SMPL-X v1.1」ボタンをクリックしてください。\n",
        "\n",
        "![SignIn](https://drive.google.com/uc?export=view&id=1cGOHUdhDtSOfIqIHYUXhQTc5ki5pgl85)\n",
        "\n",
        "4. ダウンロードしたzipファイル（models_smplx_v1_1.zip）を、`autotrace` フォルダに置いてください。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sj7qFjn46EK3"
      },
      "source": [
        "## ①　データDL\n",
        "\n",
        "Googleドライブの `autotrace` フォルダと連携します。\n",
        "\n",
        "下の【①-A】のセルを実行して、連携許可のキーを入力欄に「Ctrl+V」で貼り付けて下さい。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nZreTNgwipgE"
      },
      "source": [
        "### ①-A　Googleドライブとの連携"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "L6UsSufU6WBv"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル①-A】　Googleドライブとの連携\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "exec_dict = {}\n",
        "exec_dict['1'] = True\n",
        "\n",
        "from google.colab import drive\n",
        "import os\n",
        "\n",
        "# Googleドライブマウント\n",
        "drive.mount('/gdrive')\n",
        "\n",
        "# 起点ディレクトリ\n",
        "base_path = \"/gdrive/My Drive/autotrace\"\n",
        "\n",
        "if os.path.exists(base_path):\n",
        "    ! echo \"autotraceフォルダの中身 -----------\"\n",
        "    ! ls -l \"$base_path\"\n",
        "    ! echo \"--------------------\"\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　autotraceフォルダとの連携が成功しました。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    exec_dict['1-A'] = True\n",
        "else:\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　autotraceフォルダがGoogleドライブの直下に見つかりませんでした。\")\n",
        "    print(\"■　準備編から実行し直してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ebEeC4TE7NFE"
      },
      "source": [
        "**【OK】**\n",
        "\n",
        "下記のように、「autotrace」フォルダの中身が表示されていたら成功です。\n",
        "\n",
        "![Googleドライブ連携](https://drive.google.com/uc?export=view&id=19OhLvcyP-CN90KWDmkmBuSRR3BpO5GzV)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hLRXMSkHx4pe"
      },
      "source": [
        "### ①-B　GoogleSDKとの連携\n",
        "\n",
        "miuのGoogleドライブから必要なデータをDLするため、`GoogleSDK` と連携します。\n",
        "\n",
        "セル①-Aと同じく、URLからアクセス許可を与えてください。\n",
        "\n",
        "下の【①-B】のセルを実行して、連携許可のキーを入力欄に「Ctrl+V」で貼り付けて下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "lwhFQNTqxoOK"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル①-B】　GoogleSDKとの連携\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "# Googleドライブアクセスライブラリ\n",
        "!pip install -U -q PyDrive\n",
        "\n",
        "from pydrive.auth import GoogleAuth\n",
        "from pydrive.drive import GoogleDrive\n",
        "from google.colab import auth\n",
        "from oauth2client.client import GoogleCredentials\n",
        " \n",
        "auth.authenticate_user()\n",
        "gauth = GoogleAuth()\n",
        "gauth.credentials = GoogleCredentials.get_application_default()\n",
        "drive = GoogleDrive(gauth)\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "exec_dict['1-B'] = True\n",
        "\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "print(\"■　** OK **\")\n",
        "print(\"■　Google SDK との連携が成功しました。\")\n",
        "print(\"■■■■■■■■■■■■■■■\")\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FpsJrV-VpC29"
      },
      "source": [
        "### ①-C　Expose学習データの配置"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9rvPkHvTdNrU",
        "cellView": "form"
      },
      "source": [
        "#@markdown 下の【①-C】のセルを実行してください。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル①-C】　expose_data の配置\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "expose_data_path = f\"{base_path}/expose_data.zip\"\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not os.path.exists(expose_data_path):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　autotrace 直下に expose_data.zip が見つかりませんでした。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "else:\n",
        "    if os.path.exists('./expose_data.zip'):\n",
        "        os.remove('./expose_data.zip')\n",
        "\n",
        "    ! cp \"$expose_data_path\" .\n",
        "\n",
        "    import hashlib\n",
        "    filechecksum = 'ac8e8a53922364ed7bd04e8f9722f937b987f146f9b53f6b4317a0e69a0d055b'\n",
        "\n",
        "    with open('./expose_data.zip','rb') as f:\n",
        "        checksum = hashlib.sha256(f.read()).hexdigest()\n",
        "    if checksum == filechecksum:\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　** OK **\")\n",
        "        print(\"■　expose_data の配置が成功しました。\")\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "        exec_dict['1-C'] = True        \n",
        "    else:\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　** ERROR **\")\n",
        "        print(\"■　autotraceフォルダの expose_data のハッシュ値が一致しません。\")\n",
        "        print(\"■　配置に失敗している可能性があるので、もう一度セルを実行し直してください。\")\n",
        "        print(\"■　3回実行してもエラーになる場合、アップロードからやり直して下さい。\")\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b43Zh2-FjAeO"
      },
      "source": [
        "### ①-D　SMPL-X学習データの配置\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jLK03OXBkOuW",
        "cellView": "form"
      },
      "source": [
        "#@markdown 下の【①-D】のセルを実行してください。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル①-D】　SMPL-Xデータ の配置\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "smplx_data_path = f\"{base_path}/models_smplx_v1_1.zip\"\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not os.path.exists(smplx_data_path):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　autotrace 直下に models_smplx_v1_1.zip が見つかりませんでした。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    \n",
        "else:\n",
        "    if os.path.exists('./models_smplx_v1_1.zip'):\n",
        "        os.remove('./models_smplx_v1_1.zip')\n",
        "\n",
        "    ! cp \"$smplx_data_path\" .\n",
        "\n",
        "    import hashlib\n",
        "    filechecksum = 'cb593838a5d602395735081c7a8fd1d6b04fba261042b84e24644d875039be61'\n",
        "\n",
        "    with open('./models_smplx_v1_1.zip','rb') as f:\n",
        "        checksum = hashlib.sha256(f.read()).hexdigest()\n",
        "    if checksum == filechecksum:\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　** OK **\")\n",
        "        print(\"■　models_smplx_v1_1 の配置が成功しました。\")\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        exec_dict['1-D'] = True\n",
        "    else:\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　** ERROR **\")\n",
        "        print(\"■　autotraceフォルダの models_smplx_v1_1 のハッシュ値が一致しません。\")\n",
        "        print(\"■　配置に失敗している可能性があるので、もう一度セルを実行し直してください。\")\n",
        "        print(\"■　3回実行してもエラーになる場合、アップロードからやり直して下さい。\")\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uVf7oqzN0KJC"
      },
      "source": [
        "## **②　環境設定**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Wv4gj64t0APu"
      },
      "source": [
        "ヘッダの \"ランタイム\"　＞　\"ランタイムのタイプを変更\"　＞　\"GPU\"　を選択して下さい。\n",
        "\n",
        "変更できたら、下の【②】のセルを実行して下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "lGYV6obv0FFv",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル②】　\n",
        "#@markdown - ランタイムがGPUであることの確認\n",
        "#@markdown - 効果音を[効果音ラボ](https://soundeffect-lab.info/)様よりダウンロード\n",
        "#@markdown - Tensorflowのバージョンの変更はセル③に移動しました（2022/08/06）\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '1-D' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Dが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "exec_dict['2'] = True\n",
        "\n",
        "! echo --------------\n",
        "! echo 【A】 ランタイムをGPUに変更\n",
        "! echo --------------\n",
        "\n",
        "import os\n",
        "\n",
        "CUDA_PATH = '/usr/local/cuda-10.1'\n",
        "\n",
        "if not os.path.exists(CUDA_PATH):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　実行可能なCUDAが見つかりませんでした。\")\n",
        "    print(\"■　作者に連絡してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "p = os.getenv('PATH')\n",
        "ld = os.getenv('LD_LIBRARY_PATH')\n",
        "os.environ['PATH'] = f\"/usr/local/cuda-10.1/bin:{p}\"\n",
        "os.environ['LD_LIBRARY_PATH'] = f\"/usr/local/cuda-10.1/lib64:{ld}\"\n",
        "! nvcc --version\n",
        "\n",
        "! nvidia-smi\n",
        "\n",
        "! echo --------------\n",
        "! echo 【B】 効果音をダウンロード\n",
        "! echo --------------\n",
        "\n",
        "! wget --no-check-certificate -c \"https://soundeffect-lab.info/sound/anime/mp3/sceneswitch1.mp3\"\n",
        "\n",
        "from IPython.display import Audio, display\n",
        "def play_sound():\n",
        "    try:\n",
        "        display(Audio(\"sceneswitch1.mp3\", autoplay=True))\n",
        "    except:\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　効果音が再生できませんでした\")\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MFtzYGbg4zhJ"
      },
      "source": [
        "**【OK】**\n",
        "\n",
        "下記のように表示されて、最後に音が鳴ったら成功です。\n",
        "\n",
        "![GPU切り替え失敗](https://drive.google.com/uc?export=view&id=1WK0Oo3qQESB8hVlkvyWfsq17LUn3N308)\n",
        "\n",
        "---\n",
        "\n",
        "**【NG】**\n",
        "\n",
        "下記のように表示されていたら、ランタイムの変更に失敗しているので、導入編を再度確認して、ランタイムを変更してください。\n",
        "\n",
        "![GPU変更成功](https://drive.google.com/uc?export=view&id=1E230eOWMctbD2F7qTvn_fR-3gBRQQ_uQ)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "w0p_WxUc-jz7"
      },
      "source": [
        "## **③　コード準備**\n",
        "\n",
        "MMD自動トレースコードをColab上に構築します。\n",
        "\n",
        "下の【③】のセルを実行してください。たくさんメッセージが出ます。15分くらいかかります。\n",
        "\n",
        "**途中でコンパイルが走るので、動かなくなったように見える箇所があります。**\n",
        "\n",
        "**ビックリしたり心配になって、セルを中断しないようお願いします。そのまま待っていれば終わります。**\n",
        "\n",
        "`ERROR` という文字列が出る場合もありますが、自動トレースを実行するには問題ないエラーの可能性が高いので、一旦無視してそのまま進めて下さい。\n",
        "\n",
        "（2021/08/15時点ではERRORが1行、WARNINGが2行出ますが、どれもトレースに支障はありません。\n",
        "\n",
        "　それ以上ERRORが出た場合、インストールに失敗してる可能性が高いので、セル③をやり直してください）\n",
        "\n",
        "【②】でDLした音が鳴ったら終了です。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "PyGvHSTo-uPb",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル③】　コード準備実行\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "else:\n",
        "    import shutil\n",
        "    \n",
        "    if os.path.exists('./expose_mmd'):\n",
        "        shutil.rmtree('./expose_mmd')\n",
        "\n",
        "    # MMD自動トレースキットバージョンタグ\n",
        "    ver_tag = \"ver2.05.07.00\"\n",
        "    # ver_tag = \"work_v1.00\"\n",
        "\n",
        "    ! git clone  --depth 1 -b \"$ver_tag\" \"https://github.com/miu200521358/expose_mmd.git\"\n",
        "    \n",
        "    # tensorflow-gpu を入替\n",
        "    !pip uninstall -y tensorflow-gpu tensorflow kapre abslg numpyg wraptg gastg protobufg kerasg optg sixg wheelg tensorflowg googleg termcolorg astorg grpciog kerasg tensorboardg h5pyg markdowng werkzeugg setuptoolsg importlibg zippg typingg cachedg\n",
        "    !pip install tensorflow==1.15.2 tensorflow-gpu==1.15.2 tensorflow-probability==0.7\n",
        "\n",
        "    # %tensorflow_version 1.x\n",
        "\n",
        "    # %tensorflow_version\n",
        "\n",
        "    # 使わないtorchライブラリを削除\n",
        "    ! pip uninstall -y torchtext\n",
        "    ! pip uninstall -y torchaudio \n",
        "\n",
        "    ! pip install torch==1.6.0+cu101 torchvision==0.7.0+cu101 -f https://download.pytorch.org/whl/torch_stable.html\n",
        "    ! pip install --upgrade -r \"expose_mmd/requirements.txt\"\n",
        "\n",
        "    import os \n",
        "    p = os.getenv('PATH')\n",
        "    ld = os.getenv('LD_LIBRARY_PATH')\n",
        "    os.environ['PATH'] = f\"/usr/local/cuda-10.1/bin:{p}\"\n",
        "    os.environ['LD_LIBRARY_PATH'] = f\"/usr/local/cuda-10.1/lib64:{ld}\"\n",
        "\n",
        "    ! cd expose_mmd/lighttrack/lib/ && python setup.py install\n",
        "    ! pip3 install expose_mmd/lighttrack/lib/\n",
        "    \n",
        "    ! cd expose_mmd/lighttrack/graph/torchlight && python setup.py install\n",
        "    ! pip3 install expose_mmd/lighttrack/graph/torchlight/\n",
        "\n",
        "    exec_dict['3'] = True\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　コードの構築が完了しました。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "## **④　データ配置**\n",
        "\n",
        "MMD自動トレースに必要なデータをColab上に配置します。\n",
        "\n",
        "下の【④】のセルを実行してください。たくさんメッセージが出ます。\n",
        "\n",
        "【②】でDLした音が鳴ったら終了です。"
      ],
      "metadata": {
        "id": "YC6XbeivSxXL"
      }
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mtIz8_ixmZSj",
        "cellView": "form"
      },
      "source": [
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル④】　データの配置\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "else:\n",
        "    import os\n",
        "    import shutil\n",
        "    if os.path.exists('./data'):\n",
        "        shutil.rmtree('./data')\n",
        "\n",
        "    if os.path.exists('./models'):\n",
        "        shutil.rmtree('./models')\n",
        "\n",
        "    if os.path.exists('./expose_mmd/data/'):\n",
        "        shutil.rmtree('./expose_mmd/data/')\n",
        "\n",
        "    if os.path.exists('./expose_mmd/lighttrack/weights/'):\n",
        "        shutil.rmtree('./expose_mmd/lighttrack/weights/')\n",
        "    os.makedirs('./expose_mmd/lighttrack/weights/', exist_ok=True)\n",
        "\n",
        "    # expose関連データ移動\n",
        "    ! unzip ./expose_data.zip && mv -f data ./expose_mmd/\n",
        "    ! unzip ./models_smplx_v1_1.zip && mv -f models ./expose_mmd/data/\n",
        "\n",
        "    # backbones.zip\n",
        "    downloaded = drive.CreateFile({'id': '17Pq_Yjx2TaZeSVxE1kLkhTs8UlDgAAMd'})\n",
        "    downloaded.GetContentFile('/content/backbones.zip')\n",
        "    ! mv -f ./backbones.zip expose_mmd/lighttrack/weights/ && cd expose_mmd/lighttrack/weights && unzip -o ./backbones.zip\n",
        "\n",
        "    # CPN101.zip\n",
        "    downloaded = drive.CreateFile({'id': '10pOvWra9GysGJQxEhOj4j5VsOIWRFtlm'})\n",
        "    downloaded.GetContentFile('/content/CPN101.zip')\n",
        "    ! mv -f ./CPN101.zip expose_mmd/lighttrack/weights/ && cd expose_mmd/lighttrack/weights && unzip -o ./CPN101.zip\n",
        "\n",
        "    # GCN.zip\n",
        "    downloaded = drive.CreateFile({'id': '1KuL2uLfu-GLZLFHq7XKjjJWOjE_18Vzn'})\n",
        "    downloaded.GetContentFile('/content/GCN.zip')\n",
        "    ! mv -f ./GCN.zip expose_mmd/lighttrack/weights/ && cd expose_mmd/lighttrack/weights && unzip -o ./GCN.zip\n",
        "\n",
        "    # mobile-deconv.zip\n",
        "    downloaded = drive.CreateFile({'id': '11cMlBVuNJon_2XjXhFTXGLZXAO32k7Q3'})\n",
        "    downloaded.GetContentFile('/content/mobile-deconv.zip')\n",
        "    ! mv -f ./mobile-deconv.zip expose_mmd/lighttrack/weights/ && cd expose_mmd/lighttrack/weights && unzip -o ./mobile-deconv.zip\n",
        "\n",
        "    # MSRA152.zip\n",
        "    downloaded = drive.CreateFile({'id': '14Yz3Z_5avWFxu8MZ7vhWP2M-xPxUEQKh'})\n",
        "    downloaded.GetContentFile('/content/MSRA152.zip')\n",
        "    ! mv -f ./MSRA152.zip expose_mmd/lighttrack/weights/ && cd expose_mmd/lighttrack/weights && unzip -o ./MSRA152.zip\n",
        "\n",
        "    # YOLOv3.zip\n",
        "    downloaded = drive.CreateFile({'id': '1s9Rs90jKrlCvwM9oWgituKlo-SmPhp4q'})\n",
        "    downloaded.GetContentFile('/content/YOLOv3.zip')\n",
        "    ! mv -f ./YOLOv3.zip expose_mmd/lighttrack/weights/ && cd expose_mmd/lighttrack/weights && unzip -o ./YOLOv3.zip\n",
        "\n",
        "    # # shape_predictor_68_face_landmarks.dat.bz2\n",
        "    # downloaded = drive.CreateFile({'id': '1Gai5UVpqYJ0aWU9itFPDBu7iy53JqdV6'})\n",
        "    # downloaded.GetContentFile('/content/shape_predictor_68_face_landmarks.dat.bz2')\n",
        "    # ! mv -f ./shape_predictor_68_face_landmarks.dat.bz2 expose_mmd/data/ && cd expose_mmd/data && bunzip2 -f ./shape_predictor_68_face_landmarks.dat.bz2\n",
        "\n",
        "    exec_dict['4'] = True\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　その他のデータ の配置が成功しました。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MX_AtRSywDhD"
      },
      "source": [
        "## **⑤　入力映像アップロード**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7PLrxplXwQJW"
      },
      "source": [
        "処理したい映像ファイルを、準備してください。\n",
        "\n",
        " - ファイル名は **半角英数字のみ** にしてください。opencvは2バイト文字を読み込めません。\n",
        " - あまり長い動画はディスク容量が足りなくなります。6000fを超える場合、分割してください。\n",
        " - Googleドライブの **autotrace** フォルダ 直下に置いてください。\n",
        " - **マウント後のGooleドライブ上のファイルの上書きや更新は正しく認識されません。** 新しいファイルは新規の名前でアップロードしてから処理して下さい。\n",
        " - 入力するのは、ファイル名（拡張子含む）のみです。\n",
        " - 下の【⑤】のセルを実行して下さい。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jcveeryDv6sl",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑤】　入力映像ファイルアップロード\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "#@markdown 解析対象となる映像のファイルの名前を入力して、セルを実行してください。\n",
        "\n",
        "input_video_name = \"input.mp4\"  #@param {type: \"string\"}\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "if not exec_dict or '4' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル④が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "exec_dict['5'] = True\n",
        "\n",
        "input_video_path = f\"{base_path}/{input_video_name}\"\n",
        "\n",
        "if not os.path.exists(input_video_path):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　autotrace 直下に 指定動画 が見つかりませんでした。\")\n",
        "    print(\"■　ファイルパス: \" + input_video_path)\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "else:\n",
        "    ! cp \"$input_video_path\" .\n",
        "\n",
        "    input_video_path = f\"/content/{input_video_name}\"\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　入力動画 の設定が完了しました。\")\n",
        "    print(\"■　ファイルパス: \" + input_video_path)\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KoprSvp4xuXu"
      },
      "source": [
        "## **⑥　MMD自動トレース実行**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0g0Disv6xsmp"
      },
      "source": [
        "MMD自動トレースは人物推定・追跡指定・モーション出力に分けて実行していただきます。\n",
        "\n",
        "下の【⑥-A】のセルを実行してください。最後の変換処理で時間がかかります。\n",
        "\n",
        "※下記メッセージが出てきたら、1回目は無視して大丈夫です。\n",
        "\n",
        "2回目が出てきたら、入力映像をキリのいいところで区切って分けて処理してください。\n",
        "\n",
        "![容量オーバー](https://drive.google.com/uc?export=view&id=1EKt3nCK6ZYjgkNoflQNzSnW_0s4WnJYO)\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "XcPBwOqB4ULh"
      },
      "source": [
        "### ⑥-A　人物推定"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "2EAjUCpyyLMq"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑥-A】　人物推定\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "import shutil\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '4' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル④が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '5' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑤が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not os.path.exists('/content/expose_mmd/data') or not os.path.exists('/content/expose_mmd/data/models'):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　学習データの配置に失敗している可能性があります。\")\n",
        "    print(\"■　①-Cまで戻って、実行し直してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    \n",
        "else:\n",
        "    if os.path.exists('/content/output'):\n",
        "        shutil.rmtree('/content/output')\n",
        "\n",
        "    if os.path.exists('./out.webm'):\n",
        "        os.remove('./out.webm')\n",
        "\n",
        "    if os.path.exists('./out2.webm'):\n",
        "        os.remove('./out2.webm')\n",
        "\n",
        "    import datetime\n",
        "    process_img_dir_name = \"{0}_{1:%Y%m%d_%H%M%S}\".format(os.path.basename(input_video_path).replace('.', '_'), datetime.datetime.now())\n",
        "    process_img_dir_path = os.path.join('/content/output', process_img_dir_name)\n",
        "    os.makedirs(process_img_dir_path, exist_ok=True)\n",
        "\n",
        "    ! cd expose_mmd/ && python executor.py --video-file \"$input_video_path\" --parent-dir \"$process_img_dir_path\" --process prepare,expose,tracking --verbose 20 --log-mode 0\n",
        "\n",
        "    # mp4に変換\n",
        "    bbox_file_path = f\"{process_img_dir_path}/bbox.mp4\"\n",
        "\n",
        "    # from base64 import b64encode\n",
        "    # mp4 = open(bbox_file_path,'rb').read()\n",
        "    # data_url = \"data:video/mp4;base64,\" + b64encode(mp4).decode()\n",
        "\n",
        "    if not os.path.exists(bbox_file_path):\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "        print(\"■　** ERROR **\")\n",
        "        print(\"■　人物推定もしくは人物追跡に失敗しました。\")\n",
        "        print(\"■　「ERROR」と書かれているブロックがないか確認してください。\")\n",
        "        print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "        import sys\n",
        "        sys.exit(-1)\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** INFO **\")\n",
        "    print(\"■　セル⑥-Bを実行するための準備を開始します。\")\n",
        "    print(\"■　しばらくお待ちください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    # !ffmpeg -i \"$bbox_file_path\" -vcodec vp9 ./out.webm\n",
        "    # ! ffmpeg -i \"$bbox_file_path\" -r 30 -c:v libvpx-vp9 -threads 8 -speed 1 -tile-columns 6 -frame-parallel 1 -auto-alt-ref 1 -c:a libopus -b:a 64k -f webm ./out.webm\n",
        "    ! ffmpeg -i \"$bbox_file_path\" -c:v libvpx-vp9 -b:v 1000K -r 30 -threads 8 -speed 1 -tile-columns 6 -frame-parallel 1 -auto-alt-ref 1 -lag-in-frames 25 -c:a libopus -b:a 64k -f webm -y out.webm\n",
        "\n",
        "    # # webm形式で別途出力\n",
        "    # import os\n",
        "    # import glob\n",
        "    # import cv2\n",
        "    # from tqdm import tqdm\n",
        "\n",
        "    # def save_webm(process_img_pathes, out_path):\n",
        "    #     fourcc = cv2.VideoWriter_fourcc(*\"vp80\")\n",
        "    #     out = cv2.VideoWriter(out_path, fourcc, 30.0, (1280, 720))\n",
        "\n",
        "    #     for iidx, process_img_path in enumerate(tqdm(process_img_pathes)):\n",
        "    #         out_frame = cv2.imread(process_img_path)\n",
        "    #         out.write(out_frame)\n",
        "\n",
        "    #     out.release()\n",
        "    #     cv2.destroyAllWindows()\n",
        "\n",
        "    # process_img_pathes = sorted(glob.glob(os.path.join(process_img_dir_path, \"frames\", \"**\", \"bbox_*.png\")))\n",
        "    # process_bbox_path = \"./out.webm\"\n",
        "    # save_webm(process_img_pathes, process_bbox_path)\n",
        "\n",
        "    exec_dict['6-A'] = True\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　セル⑥-Bの実行準備が整いました。次に進んでください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xZ9PIgPIGtbZ"
      },
      "source": [
        "⑥-Aで準備した結果を、以下の観点で確認します。\n",
        "\n",
        " - 人物であろうと認識された箇所に枠が入ります。\n",
        " - 一人の人物を追いかける枠の左上にあるINDEXを確認してください。\n",
        " - 現在のフレーム番号は左上に表示しています。\n",
        " - 綺麗に人物が取れていないところは、枠が取れていても除外した方が綺麗になります。\n",
        "    - 体幹がすべて取れていて、ひじひざ辺りまで取れている枠を目安にしてください。\n",
        "    - 同じ人物に二重に枠がついてしまってる場合、より末端まで取れてる方のみ採用してください。\n",
        " - 指定方法\n",
        "   - INDEXを最初から最後まで取り入れる場合：[INDEX番号]\n",
        "   - INDEXを最初から途中まで取り入れる場合：[INDEX番号]:-[終了フレーム]\n",
        "   - INDEXを途中から最後まで取り入れる場合：[INDEX番号]:[開始フレーム]-\n",
        "   - INDEXを途中から途中まで取り入れる場合：[INDEX番号]:[開始フレーム]-[終了フレーム]\n",
        "\n",
        "---\n",
        "\n",
        "**INDEX指定例**\n",
        "\n",
        " ```\n",
        "0,44:263-,94,126,145,148,159,161:-3858,182,244,246\n",
        "1,123,157,163:3572-,170,180,208:4427-,213,239:5580-\n",
        "2,44:-261,49,61,64,71,95,135,139,146,156,188,197,205,215,247\n",
        " ```\n",
        "\n",
        "**上記INDEXの読み解き方(一行目：1人目)**\n",
        "\n",
        "1. `INDEX:0`の枠を最初から最後まで\n",
        "2. `INDEX:44`の枠の263F以降から最後まで\n",
        "3. `INDEX:94`の枠を最初から最後まで\n",
        "3. `INDEX:126`の枠を最初から最後まで\n",
        "3. `INDEX:145`の枠を最初から最後まで\n",
        "3. `INDEX:148`の枠を最初から最後まで\n",
        "3. `INDEX:159`の枠を最初から最後まで\n",
        "3. `INDEX:161`の枠を最初から3858Fまで\n",
        "3. `INDEX:182`の枠を最初から最後まで\n",
        "3. `INDEX:244`の枠を最初から最後まで\n",
        "3. `INDEX:246`の枠を最初から最後まで\n",
        "\n",
        "---\n",
        "\n",
        "下の【⑥-B】のセルを実行してください。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uToXQits4asb"
      },
      "source": [
        "### ⑥-B　人物推定結果確認"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "7lzNX_akFF-r"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑥-B】　人物推定結果確認\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "exec_dict['6-B'] = True\n",
        "\n",
        "from IPython.display import HTML\n",
        "import base64\n",
        "import io\n",
        "\n",
        "video = io.open('./out.webm', 'r+b').read()\n",
        "encoded = base64.b64encode(video)\n",
        "data  = '''\n",
        "<video id=\"out\" width=\"1280\" height=\"720\" controls><source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\" /></video>\n",
        "'''.format(encoded.decode('ascii')) + '''\n",
        "<br>\n",
        "<button id=\"prev-10frame\">10F戻る</button>\n",
        "<button id=\"prev-1frame\">1F戻る</button>\n",
        "<button id=\"prev-05frame\">0.5F戻る</button>\n",
        "<button id=\"next-05frame\">0.5F進む</button>\n",
        "<button id=\"next-1frame\">1F進む</button>\n",
        "<button id=\"next-10frame\">10F進む</button>\n",
        "（ズレた時は0.5F移動で調整してください。）\n",
        "<script type=\"text/javascript\">\n",
        "    var video = document.getElementById('out');\n",
        "    var prev05Frame = document.getElementById('prev-05frame');\n",
        "    var next05Frame = document.getElementById('next-05frame');\n",
        "    var prev1Frame = document.getElementById('prev-1frame');\n",
        "    var next1Frame = document.getElementById('next-1frame');\n",
        "    var prev10Frame = document.getElementById('prev-10frame');\n",
        "    var next10Frame = document.getElementById('next-10frame');\n",
        "    var frameRate = 1/30;\n",
        "\n",
        "    video.onloadedmetadata = function(){\n",
        "        //next\n",
        "        next05Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.min(video.duration, video.currentTime + frameRate / 2);\n",
        "        });\n",
        "\n",
        "        //prev\n",
        "        prev05Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.max(0, video.currentTime - frameRate / 2);\n",
        "        });\n",
        "\n",
        "        //next\n",
        "        next1Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.min(video.duration, video.currentTime + frameRate);\n",
        "        });\n",
        "\n",
        "        //prev\n",
        "        prev1Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.max(0, video.currentTime - frameRate);\n",
        "        });\n",
        "\n",
        "        //next\n",
        "        next10Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.min(video.duration, video.currentTime + frameRate * 10);\n",
        "        });\n",
        "\n",
        "        //prev\n",
        "        prev10Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.max(0, video.currentTime - frameRate * 10);\n",
        "        });\n",
        "    };\n",
        "</script>\n",
        "\n",
        "'''\n",
        "\n",
        "HTML(data)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1T-gKAkC3AXH",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown ※推定結果をダウンロードして確認したい場合、このセルを実行してください。\n",
        "\n",
        "#@markdown Googleドライブに「bbox.mp4」のファイル名でコピー配置します。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "drive_dir_path = os.path.join(base_path, process_img_dir_name)\n",
        "\n",
        "import os\n",
        "os.makedirs(drive_dir_path, exist_ok=True)\n",
        "\n",
        "! cp -f  \"$bbox_file_path\" \"$drive_dir_path\"\n",
        "\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "print(\"■　** OK **\")\n",
        "print(\"■　「bbox.mp4」のGoogleドライブへのコピーが完了しました。\")\n",
        "print(\"■　ファイルパス: \" + drive_dir_path + \"/bbox.mp4\")\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()\n",
        "\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "9KasFu8GVLrs"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 追跡指定タイマー\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "\n",
        "#@markdown 人物追跡指定を作成する際に、一定時間Colabを触らない時間が出来るかと思います。\n",
        "\n",
        "#@markdown 20分ほど触ってないと警告が出てしまいます。\n",
        "\n",
        "#@markdown こちらのセルを実行すると、任意分数のタイマーとなりますので、警告が出なくなります。\n",
        "\n",
        "timer_minutes = 10  #@param {type: \"number\"}\n",
        "\n",
        "#@markdown 「Ctrl+M+I」のキーボードショートカットで、タイマーを途中でストップさせる事が出来ます。\n",
        "\n",
        "from time import sleep\n",
        "from tqdm import tqdm\n",
        "\n",
        "try:\n",
        "    for _ in tqdm(range(timer_minutes * 60)):\n",
        "        sleep(1)\n",
        "except:\n",
        "    print(\"\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** INFO **\")\n",
        "    print(\"■　タイマーを中断しました。\")\n",
        "    print(\"■　次のセルを実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o1yUMzZp4fYq"
      },
      "source": [
        "### ⑥-C　人物追跡指定\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "ydpLN3F0Gk7Z"
      },
      "source": [
        "#@markdown 人物がひとりずつ動画の最後まで繋がるように、INDEXを指定して下さい。\n",
        "\n",
        "#@markdown IDが指定されている分だけ出力します。\n",
        "\n",
        "#@markdown 上から順番に1人目、2人目…となります。（最大10人まで想定）\n",
        "\n",
        "#@markdown 指定が終わったら、この【⑥-C】のセルを実行してください。このセルは繰り返し実行できます。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑥-C】　人物追跡指定\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "order_1 = \"0\"  #@param {type: \"string\"}\n",
        "\n",
        "order_2 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_3 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_4 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_5 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_6 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_7 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_8 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_9 = \"\"  #@param {type: \"string\"}\n",
        "\n",
        "order_data = [order_1, order_2, order_3, order_4, order_5, order_6, order_7, order_8, order_9]\n",
        "order_file_path = f'{process_img_dir_path}/order.csv'\n",
        "\n",
        "with open(order_file_path, 'w') as f:\n",
        "    for order in order_data:\n",
        "        f.write(order)\n",
        "        f.write(\"\\n\")\n",
        "\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "print(\"■　** OK **\")\n",
        "print(\"■　人物INDEXの指定が成功しました。\")\n",
        "print(\"■　ファイルパス: \" + order_file_path)\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "exec_dict['6-C'] = True\n",
        "\n",
        "play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fxxGD35U0OkC"
      },
      "source": [
        "### ⑥-D　追跡指定実行"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "zt1_MhU50X3J"
      },
      "source": [
        "#@markdown 先ほど指定したINDEXで人物追跡を実行します。\n",
        "\n",
        "#@markdown この【⑥-D】のセルを実行してください。最後の変換処理で時間がかかります。\n",
        "\n",
        "#@markdown このセルは繰り返し実行できます。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑥-D】　追跡指定実行\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '4' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル④が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '5' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑤が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not os.path.exists('/content/expose_mmd/data') or not os.path.exists('/content/expose_mmd/data/models'):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　学習データの配置に失敗している可能性があります。\")\n",
        "    print(\"■　①-Cまで戻って、実行し直してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    \n",
        "else:\n",
        "    ! cd expose_mmd/ && python executor.py --img-dir \"$process_img_dir_path\" --order-file \"$order_file_path\" --process order --verbose 20 --log-mode 0\n",
        "\n",
        "    # mp4に変換\n",
        "    ordered_file_path = f\"{process_img_dir_path}/ordered_bbox.mp4\"\n",
        "\n",
        "    # from base64 import b64encode\n",
        "    # mp4 = open(ordered_file_path,'rb').read()\n",
        "    # data_url = \"data:video/mp4;base64,\" + b64encode(mp4).decode()\n",
        "\n",
        "    # ! rm './out2.webm'\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** INFO **\")\n",
        "    print(\"■　セル⑥-Eを実行するための準備を開始します。\")\n",
        "    print(\"■　しばらくお待ちください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    # !ffmpeg -i \"$ordered_file_path\" -vcodec vp9 ./out2.webm\n",
        "    # ! ffmpeg -i \"$ordered_file_path\" -c:v libvpx-vp9 -b:v 1000K -threads 8 -speed 1 -tile-columns 6 -frame-parallel 1 -auto-alt-ref 1 -lag-in-frames 25 -c:a libopus -b:a 64k -f webm ./out2.webm\n",
        "    ! ffmpeg -i \"$ordered_file_path\" -c:v libvpx-vp9 -b:v 1000K -r 30 -threads 8 -speed 1 -tile-columns 6 -frame-parallel 1 -auto-alt-ref 1 -lag-in-frames 25 -c:a libopus -b:a 64k -f webm -y out2.webm\n",
        "\n",
        "    # process_img_pathes = sorted(glob.glob(os.path.join(process_img_dir_path, \"frames\", \"**\", \"order_*.png\")))\n",
        "    # process_bbox_path = \"./out2.webm\"\n",
        "    # save_webm(process_img_pathes, process_bbox_path)\n",
        "\n",
        "    exec_dict['6-D'] = True\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　セル⑥-Eの実行準備が整いました。次に進んでください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fF-DJps63lr8"
      },
      "source": [
        "### ⑥-E　追跡指定確認"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "Riv5Hvmm3RTh"
      },
      "source": [
        "#@markdown 意図した通りに人物を追跡出来ているか確認します。\n",
        "\n",
        "#@markdown この【⑥-E】のセルを実行してください。\n",
        "\n",
        "#@markdown 想定通りではなかった場合、⑥-Cに戻ってINDEXを指定し直してください。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑥-E】　追跡指定確認\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "exec_dict['6-E'] = True\n",
        "\n",
        "from IPython.display import HTML\n",
        "import base64\n",
        "import io\n",
        "\n",
        "video = io.open('./out2.webm', 'r+b').read()\n",
        "encoded = base64.b64encode(video)\n",
        "data  = '''\n",
        "<video id=\"out\" width=\"1280\" height=\"720\" controls><source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\" /></video>\n",
        "'''.format(encoded.decode('ascii')) + '''\n",
        "<br>\n",
        "<button id=\"prev-10frame\">10F戻る</button>\n",
        "<button id=\"prev-1frame\">1F戻る</button>\n",
        "<button id=\"prev-05frame\">0.5F戻る</button>\n",
        "<button id=\"next-05frame\">0.5F進む</button>\n",
        "<button id=\"next-1frame\">1F進む</button>\n",
        "<button id=\"next-10frame\">10F進む</button>\n",
        "（ズレた時は0.5F移動で調整してください。）\n",
        "<script type=\"text/javascript\">\n",
        "    var video = document.getElementById('out');\n",
        "    var prev05Frame = document.getElementById('prev-05frame');\n",
        "    var next05Frame = document.getElementById('next-05frame');\n",
        "    var prev1Frame = document.getElementById('prev-1frame');\n",
        "    var next1Frame = document.getElementById('next-1frame');\n",
        "    var prev10Frame = document.getElementById('prev-10frame');\n",
        "    var next10Frame = document.getElementById('next-10frame');\n",
        "    var frameRate = 1/30;\n",
        "\n",
        "    video.onloadedmetadata = function(){\n",
        "        //next\n",
        "        next05Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.min(video.duration, video.currentTime + frameRate / 2);\n",
        "        });\n",
        "\n",
        "        //prev\n",
        "        prev05Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.max(0, video.currentTime - frameRate / 2);\n",
        "        });\n",
        "\n",
        "        //next\n",
        "        next1Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.min(video.duration, video.currentTime + frameRate);\n",
        "        });\n",
        "\n",
        "        //prev\n",
        "        prev1Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.max(0, video.currentTime - frameRate);\n",
        "        });\n",
        "\n",
        "        //next\n",
        "        next10Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.min(video.duration, video.currentTime + frameRate * 10);\n",
        "        });\n",
        "\n",
        "        //prev\n",
        "        prev10Frame.addEventListener('click',function(){\n",
        "            video.currentTime = Math.max(0, video.currentTime - frameRate * 10);\n",
        "        });\n",
        "    };\n",
        "</script>\n",
        "\n",
        "'''\n",
        "\n",
        "HTML(data)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "P2BtROyJ4yCD"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown ※追跡指定結果をダウンロードして確認したい場合、このセルを実行してください。\n",
        "\n",
        "#@markdown Googleドライブに「ordered_bbox.mp4」のファイル名でコピー配置します。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "drive_dir_path = os.path.join(base_path, process_img_dir_name)\n",
        "\n",
        "import os\n",
        "os.makedirs(drive_dir_path, exist_ok=True)\n",
        "\n",
        "! cp -f  \"$ordered_file_path\" \"$drive_dir_path\"\n",
        "\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "print(\"■　** OK **\")\n",
        "print(\"■　「ordered_bbox.mp4」のGoogleドライブへのコピーが完了しました。\")\n",
        "print(\"■　ファイルパス: \" + drive_dir_path + \"/ordered_bbox.mp4\")\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()\n",
        "\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NizDhi8h4nG3"
      },
      "source": [
        "### ⑥-F　モーション出力"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "10ssIxUAMUl8",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 【セル⑥-F】　モーション出力\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 実行したい任意機能にチェックを入れてください。\n",
        "\n",
        "#@markdown このセルは繰り返し実行できます。\n",
        "\n",
        "# #@markdown **身体モーション出力**　（表情のみを出力したい場合などはOFFにしてください）\n",
        "\n",
        "# process_motion_body = True #@param {type:\"boolean\"}\n",
        "\n",
        "# #@markdown **上半身のみのモーション出力**　（グルーブを出力しません）\n",
        "\n",
        "# process_motion_upper = False #@param {type:\"boolean\"}\n",
        "\n",
        "#@markdown **手モーション出力**　（やや時間がかかります）\n",
        "\n",
        "process_motion_hand = False #@param {type:\"boolean\"}\n",
        "\n",
        "#@markdown **表情出力**　（そんなに時間はかかりません）\n",
        "\n",
        "process_motion_face = False #@param {type:\"boolean\"}\n",
        "\n",
        "#@markdown チェックできたら、この【⑥-F】のセルを実行してください。\n",
        "\n",
        "#@markdown Googleドライブの `autotrace`フォルダの下に「`<動画ファイル名>_<実行年月日時分秒（米国時間）>`」のフォルダの下に下記ファイルを出力しているので、それをダウンロードしてください。\n",
        "\n",
        "#@markdown     - 棒人間モデル（`trace_<実行年月日時分秒（米国時間）>_rot_model_no<追跡人物No>.pmx`）\n",
        "\n",
        "#@markdown     - 棒人間用モーション（`trace_<実行年月日時分秒（米国時間）>_rot_no<追跡人物No>.vmd`）\n",
        "\n",
        "#@markdown     - あにまさ式ミク用モーション（`trace_<実行年月日時分秒（米国時間）>_miku_smooth_no<追跡人物No>.vmd`）\n",
        "\n",
        "#@markdown     - 棒人間expose移動モーションJSONデータ（`trace_<実行年月日時分秒（米国時間）>_rot_no<追跡人物No>.json`）\n",
        "\n",
        "#@markdown     - 棒人間mediapipe移動モーションJSONデータ（`mp_trace_<実行年月日時分秒（米国時間）>_rot_no<追跡人物No>.json`）\n",
        "\n",
        "#@markdown     - JSONデータ閲覧用HTML（`viz_pos.html`）\n",
        "\n",
        "#@markdown モーションは、MMDに同梱されている「あにまさ式ミク（初音ミクVer2.pmd）」に準標準プラグインでグルーブ・上半身2ボーンを追加したモデルに準拠しています。\n",
        "\n",
        "if not exec_dict or '1-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '1-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル①-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '2' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル②が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '3' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル③が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '4' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル④が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '5' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑤が実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-A' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Aが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-B' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Bが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-C' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Cが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-D' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Dが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not exec_dict or '6-E' not in exec_dict.keys():\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　セル⑥-Eが実行されていない可能性があります。\")\n",
        "    print(\"■　目次から戻って実行してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "elif not os.path.exists('/content/expose_mmd/data') or not os.path.exists('/content/expose_mmd/data/models'):\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** ERROR **\")\n",
        "    print(\"■　学習データの配置に失敗している可能性があります。\")\n",
        "    print(\"■　①-Cまで戻って、実行し直してください。\")\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    \n",
        "else:\n",
        "    process_txt = \"mediapipe,smooth,motion\"\n",
        "\n",
        "    motion_hand_flg = \"1\" if process_motion_hand else \"0\"\n",
        "    motion_face_flg = \"1\" if process_motion_face else \"0\"\n",
        "\n",
        "    ! cd expose_mmd/ && python executor.py --img-dir \"$process_img_dir_path\" --order-file \"$order_file_path\" --process $process_txt --hand-motion $motion_hand_flg --face-motion $motion_face_flg --verbose 20 --log-mode 0\n",
        "\n",
        "    import shutil\n",
        "\n",
        "    # 日本語対策でpythonコピー\n",
        "    output_name = os.path.basename(input_video_name).replace('.', '_')\n",
        "    output_path = os.path.join(base_path, process_img_dir_name)\n",
        "\n",
        "    os.makedirs(output_path, exist_ok=True)\n",
        "\n",
        "    import glob\n",
        "    for target_file_name in [\"trace_*_mov_model_no*.pmx\", \"trace_*_rot_model_no*.pmx\", \"trace_*_mov_no*.vmd\", \"trace_*_rot_no*.vmd\", \"trace_*_miku_smooth_no*.vmd\", \"*.json\"]:\n",
        "        for vmd_path in glob.glob(os.path.join(process_img_dir_path, \"motion\", target_file_name)):\n",
        "            out_vmd_path = os.path.join(output_path, os.path.basename(vmd_path))\n",
        "            shutil.copy(vmd_path, out_vmd_path)\n",
        "\n",
        "    shutil.copy(f'{process_img_dir_path}/ordered_bbox.mp4', output_path)\n",
        "    shutil.copy('expose_mmd/viz_pos.html', output_path)\n",
        "\n",
        "    exec_dict['6-F'] = True\n",
        "\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "    print(\"■　** OK **\")\n",
        "    print(\"■　モーションの出力が成功しました。\")\n",
        "    print(\"■　ファイルパス: \" + output_path)\n",
        "    print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "    play_sound()\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LnAUBEOeHoPe"
      },
      "source": [
        "# 自動トレース後の作業"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Vu4_v1zqH2gM"
      },
      "source": [
        "## ①　GoogleドライブにVMDが出力されない場合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0BFA_3plH8Y7"
      },
      "source": [
        " - **ERROR**　**CRITICAL**　というメッセージが出ていないか確認してください。\n",
        " - メッセージが出ていない場合、処理出力フォルダにVMDファイルが出力されているか確認してください。\n",
        "   1. 画面左のフォルダーボタンをクリックしてください。\n",
        "\n",
        " ![フォルダーボタン](https://drive.google.com/uc?export=view&id=1AoTQjFHaz2uY4jGJttmVRkWk2nct2kb3)\n",
        "\n",
        "   2. `output/<動画ファイル名>_<実行年月日>_<実行時分秒>/motion` フォルダの下にファイルが出来ているか確認してください。\n",
        "\n",
        " ![motionフォルダ](https://drive.google.com/uc?export=view&id=1wJsomaHWFwSyt6lmt7Zuli8AJ-cxi3uX)\n",
        "\n",
        "     - PMXファイルやVMDファイルがある場合、それをダウンロードしてください。\n",
        "        - 必要なファイルは【⑥-F】に記載してます。\n",
        "        - ファイルを選択して右クリックすることで、メニューが表示されます。\n",
        "     - PMXファイルやVMDファイルがない場合、どこかでエラーが発生しています。\n",
        "     - エラーの原因が分からない場合は、ノートブックを共有してください。\n",
        "       - 共有方法は、「[準備編](https://colab.research.google.com/github/miu200521358/motion_trace_colab/blob/master/AutoTraceIntroduction.ipynb)」を確認してください。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qxwONV2ULFc_"
      },
      "source": [
        "## ② 　関節位置データが欲しい場合"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vDutzsxhGKcy"
      },
      "source": [
        "関節位置データ（姿勢推定・人物追跡・表情認識の結果データ）が必要な場合、\n",
        "\n",
        "下のセルを実行すると、Googleドライブに該当データを固めたzipがコピーされるので、それをダウンロードしてください。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "B4GLtUJIGMNu",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown 生データが欲しい場合、このセルを実行してください。\n",
        "\n",
        "#@markdown コピーが完了してから、Googleドライブ上で見えるようになるまで数分かかります。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "json_org_path = os.path.join(process_img_dir_path, 'ordered')\n",
        "zip_name = f'{os.path.basename(process_img_dir_path)}_ordered.zip'\n",
        "zip_path = os.path.join(process_img_dir_path, zip_name)\n",
        "drive_zip_path = os.path.join(base_path, zip_name)\n",
        "\n",
        "! zip -r \"$drive_zip_path\" \"$json_org_path\"\n",
        "\n",
        "# ! echo \"$drive_zip_path\"\n",
        "# ! echo \"$zip_path\"\n",
        "\n",
        "# ! cp \"$zip_path\" \"$drive_zip_path\"\n",
        "\n",
        "# import shutil\n",
        "# shutil.copyfile(zip_name, )\n",
        "\n",
        "# import shutil\n",
        "# shutil.copytree(f'{process_img_dir_path}/ordered', json_path)\n",
        "\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "print(\"■　** OK **\")\n",
        "print(\"■　生データのGoogleドライブへのコピーが完了しました。\")\n",
        "print(\"■　ファイルパス: \" + drive_zip_path)\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "2uIu8L07HMMz",
        "cellView": "form"
      },
      "source": [
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "#@markdown スムージング後データが欲しい場合、このセルを実行してください。\n",
        "\n",
        "#@markdown コピーが完了してから、Googleドライブ上で見えるようになるまで数分かかります。\n",
        "\n",
        "#@markdown ■■■■■■■■■■■■■■■■■■\n",
        "\n",
        "json_org_path = os.path.join(process_img_dir_path, 'smooth')\n",
        "zip_name = f'{os.path.basename(process_img_dir_path)}_smooth.zip'\n",
        "zip_path = os.path.join(process_img_dir_path, zip_name)\n",
        "drive_zip_path = os.path.join(base_path, zip_name)\n",
        "\n",
        "! zip -r \"$drive_zip_path\" \"$json_org_path\"\n",
        "\n",
        "# ! echo \"$drive_zip_path\"\n",
        "# ! echo \"$zip_path\"\n",
        "\n",
        "# ! cp \"$zip_path\" \"$drive_zip_path\"\n",
        "\n",
        "# import shutil\n",
        "# shutil.copyfile(zip_name, )\n",
        "\n",
        "# import shutil\n",
        "# shutil.copytree(f'{process_img_dir_path}/smooth', json_path)\n",
        "\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "print(\"■　** OK **\")\n",
        "print(\"■　スムージング後データのGoogleドライブへのコピーが完了しました。\")\n",
        "print(\"■　ファイルパス: \" + drive_zip_path)\n",
        "print(\"■■■■■■■■■■■■■■■\")\n",
        "\n",
        "play_sound()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "O1U9nW7Fl6Bv"
      },
      "source": [
        "## ③　奥行きやジャンプを修正したい場合\n",
        "\n",
        "全親で大体の奥行き（センターZ）、横移動量（センターX）を入力した後、[モーションサポーター](https://seiga.nicovideo.jp/seiga/im10581987) の「全親移植」を使用してください。\n",
        "\n",
        "センターYはグルーブに分けてますので、ジャンプの修正は、手動の方が綺麗になると思います。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "IkwK61mP32Tn"
      },
      "source": [
        "## ④　足FKデータを足IKデータに変換したい場合\n",
        "\n",
        "[モーションサポーター](https://seiga.nicovideo.jp/seiga/im10581987) の「足FKtoIK」を使用してください。\n",
        "\n",
        "**オススメ設定**\n",
        "\n",
        " 1. 「足首水平化：チェックON」「かかと・つま先Y=0」で「足FKtoIK」実行\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o5BxR5tGM2k-"
      },
      "source": [
        "## ⑤　全打ちデータから、不要キーを除きたい場合\n",
        "\n",
        "[モーションサポーター](https://seiga.nicovideo.jp/seiga/im10581987) の「スムージング」を使用してください。\n",
        "\n",
        "※スムージングの不要キー削除処理を行うとオリジナルの動きから若干ズレます\n",
        "\n",
        "**オススメ設定**\n",
        "\n",
        " 1. 「処理対象：全ボーン・モーフ」「処理回数：4」「補間方法：補間曲線に従う」「不要キー削除処理を追加実行する：チェックON」でスムージング\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "K-SMqIYJMa2p"
      },
      "source": [
        "## ⑥　あにまさ式ミクから他のモデルに合わせたモーションデータに変換したい場合\n",
        "\n",
        "[VMDサイジング](https://seiga.nicovideo.jp/seiga/im9755721) を使用してください。\n",
        "\n",
        "**元モデルの作成方法**\n",
        "\n",
        "1. そぼろ様の [準標準プラグイン](http://www.nicovideo.jp/watch/sm14956092) をPmxEditorに導入する\n",
        "2. PmxEditorを起動する\n",
        "3. MMDに同梱されている「初音ミクVer2.pmd」を読み込む\n",
        "4. 準標準プラグインを実行し、「全ての親」「グルーブ」「上半身2」を導入する\n",
        "\n",
        "**オススメ設定**\n",
        "\n",
        "1. 「元モデル：あにまさ式ミク準標準」「スタンス追加補正：ON」「捩り分散：ON」でお好きなモデルに合わせてサイジング\n",
        "\n",
        "**オススメの作業順番**\n",
        "\n",
        "1. センター位置調整（あにまさ式ミク：手動）\n",
        "2. 全親移植③（あにまさ式ミク：モーションサポーター）\n",
        "3. 足FKtoIK④（あにまさ式ミク：モーションサポーター）\n",
        "4. スムージング⑤（あにまさ式ミク：モーションサポーター）\n",
        "3. サイジング⑥（あにまさ式ミク　→　任意のモデル：VMDサイジング）\n",
        "4. モーション修正（任意のモデル：手動）\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HDG_5rZFaiha"
      },
      "source": [
        "## ⑥　別の動画をトレースしたい場合\n",
        "\n",
        "Colab環境は、90分無操作でなければ、12時間の間は環境が保持されます。\n",
        "\n",
        "④から別の動画をアップロードしてやり直す事ができます。\n",
        "\n",
        "\n",
        "※下記のようなエラーが出た場合、環境が既に破棄されています。\n",
        "\n",
        "目次からセル①に戻って、すべて実行し直してください。\n",
        "\n",
        "![Googleドライブ連携](https://drive.google.com/uc?export=view&id=1Tsjzs2QAECPMfUTaTh7PYX2cMEypEIF2)\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9nm28k-hcifr"
      },
      "source": [
        "## ⑦　最初からやり直したい場合\n",
        "\n",
        "1. メニューの「ランタイム」＞「ランタイムを出荷状態にリセット」＞「はい」をクリックしてください。\n",
        "\n",
        " ![リセット](https://drive.google.com/uc?export=view&id=1Eyi6OLpndFo63tyJsMtukIiL9p4wqBJs)\n",
        "\n",
        "2. メニュー右上の「再接続」をクリックしてください。\n",
        "\n",
        " ![再接続](https://drive.google.com/uc?export=view&id=1h7jF222tU4ZQz_jIMeDKYb9CNIbHTN1k)\n",
        "\n",
        "3. 緑のチェックマークがついたらリセット完了です。\n",
        "\n",
        " ![リセット完了](https://drive.google.com/uc?export=view&id=1FXq971EddklGtHMHpm_vQM0MtRvQrJ-y)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kbsMHQ7QM8zm"
      },
      "source": [
        "# ライセンス・クレジット"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KV5FmXRDdKwN"
      },
      "source": [
        "MMD自動トレースの結果を公開・配布する場合は、必ずライセンスのご確認をお願い致します。Unity等他への適用の場合も同様です。\n",
        "\n",
        "[MMD自動トレースv2 ライセンス・クレジット](https://github.com/miu200521358/expose_mmd/wiki/MMD自動トレースv2-ライセンス・クレジット)"
      ]
    }
  ]
}